package net.za.cair.dip.transform;

import java.util.ArrayList;

import net.za.cair.dip.model.MaterializationRank;
import net.za.cair.dip.model.MaterializationRanking;
import net.za.cair.dip.model.OntologyStructure;
import net.za.cair.dip.model.Rank;
import net.za.cair.dip.model.Ranking;

import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLException;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;

/*
 * Copyright (C) 2011, Centre for Artificial Intelligence Research
 *
 * Modifications to the initial code base are copyright of their
 * respective authors, or their employers as appropriate.  Authorship
 * of the modifications may be determined from the ChangeLog placed at
 * the end of this file.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

/**
 * Author: Kody Moodley<br>
 * Centre for Artificial Intelligence Research<br>
 * UKZN and CSIR<br>
 * Date: 10-Oct-2011<br><br>
 */

public class RationalRankingAlgorithm{
	
	private OntologyStructure ontologyStructure;
	private OWLReasonerFactory reasonerFactory;
	
	private Ranking rankingTmp;
	private MaterializationRanking ranking;
	
	public RationalRankingAlgorithm(OWLReasonerFactory reasonerFactory, OntologyStructure ontologyStructure){
		this.ontologyStructure = ontologyStructure;
		this.reasonerFactory = reasonerFactory;
		rankingTmp = new Ranking();
		ranking = new MaterializationRanking();
	}
	
	public MaterializationRanking computeRanking() throws OWLException{
		
		ArrayList<ArrayList<OWLAxiom>> eT;
		ArrayList<ArrayList<OWLAxiom>> dT;
				
		AxiomETransformFactory eFactory = new AxiomETransformFactory(reasonerFactory, ontologyStructure);
		eT = eFactory.generateETransforms();
		eT = removeEmptyRanks(eT);														//remove empty ranks

		ArrayList<ArrayList<OWLAxiom>> new_dT = new ArrayList<ArrayList<OWLAxiom>>();

		if (!eT.isEmpty()){
			DTransformFactory dFactory = new DTransformFactory(eT);
			dT = dFactory.getDTransforms();
			
			for (ArrayList<OWLAxiom> tmp: dT){
				if (!tmp.equals(eFactory.infiniteRank))
					new_dT.add(tmp);
			}
		}
		
		/** Generate infinite rank **/
		
		ArrayList<OWLAxiom> infiniteRank = new ArrayList<OWLAxiom>();
		infiniteRank.addAll(eFactory.infiniteRank);
		infiniteRank.addAll(ontologyStructure.sBox.getAxioms());
		infiniteRank.addAll(ontologyStructure.bBox.getAxioms());
		rankingTmp.add(new Rank(infiniteRank));											//add infinite rank
		
		for (ArrayList<OWLAxiom> dTRank: new_dT){										//add other ranks
			rankingTmp.add(new Rank(dTRank));
		}
		
		convert(rankingTmp);															//convert to materialization form
		return ranking;	
	}
	
	private void convert(Ranking ranking){
		for (Rank rank: ranking.getRanking()){
			MaterializationRank tmp = rank.materialConversion();
			if (tmp.size() > 0)
				this.ranking.add(tmp);
		}
	}
	
	private ArrayList<ArrayList<OWLAxiom>> removeEmptyRanks(ArrayList<ArrayList<OWLAxiom>> set){
		ArrayList<ArrayList<OWLAxiom>> result = new ArrayList<ArrayList<OWLAxiom>>();
		for (ArrayList<OWLAxiom> tmp: set){
			if (!tmp.isEmpty()){
				result.add(tmp);
			}
		}
		return result;
	}
	
	public Ranking getDisplayableRanking(){
		return rankingTmp;
	}
}
